package com.fdb.efp.basic.framework.mail.send;

import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;

import com.fdb.efp.basic.framework.mail.common.MailContentType;
import com.fdb.efp.basic.framework.mail.config.MailConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import jodd.mail.Email;
import jodd.mail.EmailAttachment;
import jodd.mail.MailServer;
import jodd.mail.SendMailSession;
import jodd.mail.SmtpServer;

 /**
  * 默认的邮件发送器，使用Jodd实现
  * @author gcb
  * @since 2019年3月15日 下午3:48:02
  * @version 1.0
  */
public class DefaultEmailSenderImpl implements ConfigurableMailSender {

    Logger logger = LoggerFactory.getLogger(DefaultEmailSenderImpl.class);

    private MailConfig config;

    public DefaultEmailSenderImpl(MailConfig config) {
        this.config = config.copy(); // DO NOT change config, keep it immutable !!
    }

    @Override
    public boolean send(String content, String subject, String remoteAddr, MailContentType type) {
        return send(content, subject, remoteAddr, type, null);
    }

    @Override
    public boolean send(
        String content, 
        String subject, 
        String remoteAddr, 
        MailContentType type, 
        Map<String, byte[]> attachments) {
        Email email = Email.create()
            .from(config.localAddress())
            .to(remoteAddr)
            .subject(subject);

        if (attachments != null) {
            Iterator<Entry<String, byte[]>> it = attachments.entrySet().iterator();
            while (it.hasNext()) {
                Entry<String, byte[]> entry = it.next();
                email.attachment(EmailAttachment.with().name(entry.getKey()).content(entry.getValue()));
            }
        }

        switch (type) {
        case TEXT: 
            email = email.textMessage(content); break;
        case HTML: 
            email = email.htmlMessage(content); break;
        default:
            logger.error("非法的MailContentType");
            return false;
        }
        return doSend(email);
    }

    private boolean doSend(Email email) {
        final MailConfig local = this.config;
        SmtpServer smtpServer = createServer(local);
        SendMailSession session = smtpServer.createSession();
        try {
            session.open();
            session.sendMail(email);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            logger.error(e.getMessage());
            return false;
        } finally {
            session.close();
        }
    }

    private SmtpServer createServer(MailConfig config) {
        MailServer.Builder builder = MailServer.create()
                .host(config.serverAddress()).port(config.port());
        if (config.username() != null && config.password() != null) {
            builder = builder.auth(config.username(), config.password())
                    .ssl(config.ssl());
        }
        return builder.buildSmtpMailServer();
    }

    @Override
    public void setConfig(MailConfig config) {
        this.config = config.copy();
    }
}
